// This File is part of the "nyaqt" Project
// 
// Copyright  2009 sometmes@gmail.com
// All rights reserved
// 
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Resources;
using System.Collections;

namespace ResourceCompare
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        List<ResXElement> _file1List = null;
        List<ResXElement> _file2List = null;
        SortedList<string, ResXElement> _file1BaseSortedList = null;

        List<ResXCompareElement> _compareList = null;

        private void Form1_Load(object sender, EventArgs e)
        {
            LoadResources();
        }

        ResXCompareElement CheckBase(ResXCompareElement xe, SortedList<string, ResXElement> baseleft)
        {
            if (baseleft == null)
            {
                xe.HasBase = HasBaseEnum.Unknown;
                return xe;
            }

            if (baseleft.ContainsKey(xe.Name))
                xe.HasBase = HasBaseEnum.HasBase;
            else
                xe.HasBase = HasBaseEnum.NoBase;

            return xe;
        }

        void Compare(List<ResXCompareElement> compareList, List<ResXElement> left, List<ResXElement> right, SortedList<string, ResXElement> baseleft)
        {
            List<ResXElement> sleft = new List<ResXElement>(left);
            sleft.Sort();
            List<ResXElement> sright = new List<ResXElement>(right);
            sright.Sort();

            bool done = false;
            int li = 0;
            int ri = 0;
            ResXElement le;
            ResXElement re;
            while (!done)
            {
                if (li < sleft.Count)
                    le = sleft[li];
                else
                    le = null;
                if (ri < sright.Count)
                    re = sright[ri];
                else
                    re = null;

                if (le != null && re != null && le.Name == re.Name)
                {
                    compareList.Add(CheckBase(new ResXCompareElement(le, re),baseleft));
                    li += 1;
                    ri += 1;
                }
                else if (le != null && re != null && le.Name.CompareTo(re.Name) < 0)
                {
                    compareList.Add(CheckBase(new ResXCompareElement(le, new ResXElement(le.Name, null)),baseleft));
                    li += 1;
                }
                else if (le != null && re != null && le.Name.CompareTo(re.Name) > 0)
                {
                    compareList.Add(CheckBase(new ResXCompareElement(new ResXElement(re.Name, null), re),baseleft));
                    ri += 1;
                }
                else if (le != null && re == null)
                {
                    compareList.Add(CheckBase(new ResXCompareElement(le, new ResXElement(le.Name, null)),baseleft));
                    li += 1;
                }
                else if (le == null && re != null)
                {
                    compareList.Add(CheckBase(new ResXCompareElement(new ResXElement(re.Name, null), re),baseleft));
                    ri += 1;
                }
                else if (le == null && re == null)
                {
                    done = true;
                }
                else
                    throw new SystemException("No contemplado");                
            }
        }

        private static void LoadResX(string file, List<ResXElement> list, SortedList<string, ResXElement> sortedList)
        {
            if (!Path.IsPathRooted(file))
                file = Path.Combine(Application.StartupPath, file);

            using (ResXResourceReader reader = new ResXResourceReader(file))
            {
                reader.UseResXDataNodes = false;
                foreach (DictionaryEntry entry in reader)
                {
                    string name = entry.Key as string;
                    object value = entry.Value;
                    ResXElement xe = new ResXElement(name,value);
                    xe.Original = true;
                    if (list != null)
                        list.Add(xe);
                    if (sortedList != null)
                        sortedList.Add(name, xe);
                }
                reader.Close();
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {

        }

        private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            ResXCompareElement xe = dataGridView1.Rows[e.RowIndex].DataBoundItem as ResXCompareElement;
            if (e.ColumnIndex == 1) //Left Value
            {
                if (xe.HasBase == HasBaseEnum.HasBase && xe.LeftValue == null)
                    e.CellStyle.BackColor = Color.LightCoral;
                else if (xe.HasBase == HasBaseEnum.NoBase && xe.LeftValue != null)
                    e.CellStyle.BackColor = Color.LightGoldenrodYellow;
            }
            else if (e.ColumnIndex == 2) //Right Value
            {
                if (xe.LeftValue == null && xe.RightValue != null)
                    e.CellStyle.BackColor = Color.LightGoldenrodYellow;
                else if (xe.LeftValue != null && xe.RightValue == null)
                    e.CellStyle.BackColor = Color.LightCoral;
            }
        }

        private void openToolStripButton_Click(object sender, EventArgs e)
        {
            LoadResources();
        }

        private void LoadResources()
        {
            _file1List = null;
            _file2List = null;
            _file1BaseSortedList = null;
            string file;
            if (FilesTextBox.Lines.Length > 0)
            {
                file = FilesTextBox.Lines[0];
                _file1List = new List<ResXElement>();
                LoadResX(file, _file1List, null);
            }
            if (FilesTextBox.Lines.Length > 1)
            {
                file = FilesTextBox.Lines[1];
                _file2List = new List<ResXElement>();
                LoadResX(file, _file2List, null);
            }
            if (FilesTextBox.Lines.Length > 2)
            {
                file = FilesTextBox.Lines[2];
                _file1BaseSortedList = new SortedList<string, ResXElement>();
                LoadResX(file, null, _file1BaseSortedList);
            }

            _compareList = new List<ResXCompareElement>();
            Compare(_compareList, _file1List, _file2List, _file1BaseSortedList);
            BindGrid();
        }

        private void BindGrid()
        {
            if (hideUnchagedItemsToolStripMenuItem.Checked)
            {
                List<ResXCompareElement> interest = _compareList.FindAll(ResXCompareElement.IsInteresting);
                dataGridView1.DataSource = interest;
            }
            else
                dataGridView1.DataSource = _compareList;

            dataGridView1.Columns["HasBase"].Visible = false;
        }

        private void hideUnchagedItemsToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
        {
            BindGrid();
        }

        private void saveToolStripButton_Click(object sender, EventArgs e)
        {

        }
    }
}
